import axios from "axios";
import router from "@/router";
import { isAuthenticated, getToken, removeToken } from "@/utils/auth";

// 常量定义
const SAP_SUCCESS_CODE = "S";
const SAP_ERROR_CODE = "E";
const HTTP_SUCCESS_CODE = 200;

// 环境变量
const proxyUrl = import.meta.env.VITE_API_SAP_PROXY;
const baseURL = import.meta.env.VITE_API_ROOT;

// 存储所有取消令牌的Map
const cancelTokenMap = new Map();

/**
 * 处理SAP接口响应数据
 * @param {Object} proxyData 代理返回的数据
 * @returns {Object} 处理后的数据
 */
const handleSapResponse = (proxyData) => {
  if (proxyData.code !== HTTP_SUCCESS_CODE) {
    return {
      status: SAP_ERROR_CODE,
      message: proxyData.message || "JAVA请求转发失败",
      originalData: proxyData,
    };
  }

  try {
    const result = JSON.parse(proxyData.result);
    const { RTYPE, RTMSG, ET_DATA } = result;

    if (RTYPE !== SAP_SUCCESS_CODE) {
      return {
        status: RTYPE || SAP_ERROR_CODE,
        message: RTMSG || "SAP接口请求失败",
        originalData: result,
      };
    }

    // 处理ET_DATA可能是字符串或对象的情况
    return typeof ET_DATA === "string" ? JSON.parse(ET_DATA) : ET_DATA;
  } catch (error) {
    return {
      status: SAP_ERROR_CODE,
      message: "响应数据解析失败",
      error,
      originalData: proxyData,
    };
  }
};

/**
 * 封装SAP GET请求
 * @param {string} url 请求路径
 * @param {Object} params 请求参数
 * @param {boolean} cancelable 是否允许取消
 * @param {string} requestId 请求唯一标识(用于取消)
 * @returns {Promise} 返回Promise对象
 */
export const sapGetRequest = async (url, params, cancelable = false, requestId = '') => {
  const realUrl = `${baseURL}${url}`;
  
  // 配置取消令牌
  let cancelToken;
  if (cancelable && requestId) {
    // 如果已有相同requestId的请求，先取消
    if (cancelTokenMap.has(requestId)) {
      cancelTokenMap.get(requestId).cancel('取消重复请求');
      cancelTokenMap.delete(requestId);
    }
    
    cancelToken = axios.CancelToken.source();
    cancelTokenMap.set(requestId, cancelToken);
  }

  try {
    const response = await axios.post(proxyUrl, {
      url: realUrl,
      data: params,
    }, {
      cancelToken: cancelable ? cancelToken?.token : undefined
    });

    // 请求成功后从map中移除
    if (cancelable && requestId) {
      cancelTokenMap.delete(requestId);
    }

    return handleSapResponse(response.data);
  } catch (error) {
    // 如果是主动取消的请求，不处理
    if (axios.isCancel(error)) {
      return Promise.reject({
        status: 'CANCEL',
        message: '请求已取消',
        isCanceled: true
      });
    }

    // 统一错误处理
    const errorInfo = {
      status: SAP_ERROR_CODE,
      message: "网络请求失败",
      error: error.message,
      stack: error.stack,
    };

    // 如果是axios错误，可以获取更多信息
    if (axios.isAxiosError(error)) {
      errorInfo.response = error.response?.data;
      errorInfo.statusCode = error.response?.status;
    }

    return Promise.reject(errorInfo);
  }
};

/**
 * 取消指定请求
 * @param {string} requestId 请求唯一标识
 * @param {string} message 取消信息
 */
export const cancelRequest = (requestId, message = '手动取消请求') => {
  if (cancelTokenMap.has(requestId)) {
    cancelTokenMap.get(requestId).cancel(message);
    cancelTokenMap.delete(requestId);
  }
};

/**
 * 取消所有可取消的请求
 */
export const cancelAllRequests = () => {
  cancelTokenMap.forEach((cancelToken, requestId) => {
    cancelToken.cancel('取消所有请求');
    cancelTokenMap.delete(requestId);
  });
};

// 可选：添加请求拦截器
axios.interceptors.request.use(
  (config) => {
    // 可以在这里统一添加token等逻辑
    if (isAuthenticated()) {
      config.headers["Token"] = getToken();
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 可选：添加响应拦截器
axios.interceptors.response.use(
  (response) => {
    // 可以在这里统一处理响应
    const res = response.data;
    // token失效（后台状态码没有统一 只能这样兼容判断了。。。）
    if (res.code === 5000 && res.message?.indexOf("token") !== -1) {
      removeToken();
      router.replace({
        path: "/autoLogin",
      });
      return Promise.reject(new Error(res.message));
    } else {
      return response;
    }
  },
  (error) => {
    // 如果是取消请求的错误，直接抛出
    if (axios.isCancel(error)) {
      return Promise.reject({
        status: 'CANCEL',
        message: error.message,
        isCanceled: true
      });
    }
    // 统一处理响应错误
    return Promise.reject(error);
  }
);